package com.zmn.oms.zmn.business.impl.statistics;

import com.google.common.collect.Lists;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderWork;
import com.zmn.oms.business.interfaces.es.OrderWorkEsBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.dio.normal.statistics.MasterOrderStatDIO;
import com.zmn.oms.common.dro.statistics.MasterOrderStatDRO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.zmn.business.interfaces.statistics.StatOrderBService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.filter.ParsedFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;

/**
 * 类描述：工单统计
 *
 * @author liuyufan
 * @date 2021/12/6
 */
@Slf4j
@Service
public class StatOrderBServiceImpl implements StatOrderBService {
    @Autowired
    private OrderWorkEsBService orderWorkEsBService;

    @Override
    public MasterOrderStatDRO getOrderStatByMasterId(MasterOrderStatDIO masterOrderStatDIO) throws OmsBaseException {
        log.info("订单统计-工程师派单时间内总单,失败单数量，入参：{}", masterOrderStatDIO);

        this.validateTime(masterOrderStatDIO);

        // 过滤条件
        Integer masterId = masterOrderStatDIO.getMasterId();
        String startDate = masterOrderStatDIO.getStartDate();
        String endDate = masterOrderStatDIO.getEndDate();
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .filter(QueryBuilders.termQuery("masterId", masterId))
                .filter(QueryBuilders.termQuery("isTest", false))
                .filter(QueryBuilders.termQuery("isDuplicate", false))
                .filter(QueryBuilders.rangeQuery("distributeTime").gte(startDate))
                .filter(QueryBuilders.rangeQuery("distributeTime").lte(endDate))
                .filter(QueryBuilders.termsQuery("type", Lists.newArrayList(OrderConsts.ORDER_TYPE_NEW, OrderConsts.ORDER_TYPE_REWORK)));

        // 聚合操作
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        NativeSearchQuery build = nativeSearchQueryBuilder.withQuery(queryBuilder)
                .withPageable(Pageable.unpaged())
                .addAggregation(AggregationBuilders.filter("failOrder", QueryBuilders.boolQuery()
                        .filter(QueryBuilders.termsQuery("resultStatus", Arrays.asList(OrderStatusConsts.WORK_RESULT_DISCARD, OrderStatusConsts.WORK_RESULT_FAIL)))))
                .build();

        Aggregations aggregations = orderWorkEsBService.getAggregationsByQuery(build);
        MasterOrderStatDRO result = new MasterOrderStatDRO();
        result.setOrderCount(build.getMaxResults());
        Long inWarrantyCount = ((ParsedFilter) aggregations.get("failOrder")).getDocCount();
        result.setFailCount(inWarrantyCount.intValue());

        log.info("订单统计-工程师派单时间内总单,失败单数量，出参：{}", result);
        return result;

    }

    @Override
    public Long countCompletedOrderByCompleteId(Long completerId, String startTime, String endTime) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .filter(QueryBuilders.termQuery("completerId", completerId));

        RangeQueryBuilder timeRange = QueryBuilders.rangeQuery("completeTime");
        timeRange.gte(startTime);
        if (StringUtils.isNotBlank(endTime)) {
            timeRange.lte(endTime);
        }
        queryBuilder.filter(timeRange);

        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        NativeSearchQuery build = nativeSearchQueryBuilder.withQuery(queryBuilder)
                .withPageable(Pageable.unpaged()).build();

        Long count = orderWorkEsBService.countByQuery(build);
        return count;
    }

    /**
     * 验证时间格式
     *
     * @param masterOrderStatDIO
     * @throws OmsBaseException
     */
    private void validateTime(MasterOrderStatDIO masterOrderStatDIO) throws OmsBaseException {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        try {
            //Java 8 新添API 用于解析日期和时间
            LocalDateTime.parse(masterOrderStatDIO.getStartDate(), dtf);
            LocalDateTime.parse(masterOrderStatDIO.getEndDate(), dtf);
        } catch (Exception e) {
            log.info("入参时间格式异常:{}", e.getMessage());
            throw new OmsBaseException("入参时间格式异常:" + e.getMessage());
        }
    }
}
